package cn.org.eshow.service.impl;

import cn.org.eshow.bean.query.OrderItemQuery;
import cn.org.eshow.bean.query.ProductOrderQuery;
import cn.org.eshow.bean.query.ProductOrderQuery;
import cn.org.eshow.common.ShopDataVar;
import cn.org.eshow.common.page.Page;
import cn.org.eshow.component.getui.GetuiUtil;
import cn.org.eshow.component.pingpay.config.PingConfig;
import cn.org.eshow.dao.ProductOrderDao;
import cn.org.eshow.model.*;
import cn.org.eshow.service.*;
import cn.org.eshow.util.OrderUtil;
import cn.org.eshow.util.StringUtil;
import com.pingplusplus.Pingpp;
import com.pingplusplus.model.Charge;
import com.pingplusplus.model.Refund;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.jws.WebService;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.org.eshow.component.getui.GetuiUtil.pushMessage;

//import cn.org.eshow.service.MoneyManager;

@WebService(serviceName = "ProductOrderService", endpointInterface = "cn.org.eshow.service.ProductOrderManager")
@Service
public class ProductOrderManagerImpl extends GenericManagerImpl<ProductOrder, Integer> implements ProductOrderManager {

    @Autowired
    ProductOrderDao productOrderDao;
    @Autowired
    OrderStepManager orderStepManager;
    @Autowired
    BillManager billManager;
    @Autowired
    FinanceManager financeManager;
    @Autowired
    OrderItemManager orderItemManager;
    @Autowired
    ProductManager productManager;
    @Autowired
    UserCouponManager userCouponManager;
    @Autowired
    ProductItemManager productItemManager;
    @Autowired
    NotificationManager notificationManager;
    @Autowired
    MoneyManager moneyManager;

    public ProductOrderManagerImpl() {
    }

    @Autowired
    public ProductOrderManagerImpl(ProductOrderDao productOrderDao) {
        super(productOrderDao);
        this.productOrderDao = productOrderDao;
    }

    @Override
    public List<ProductOrder> list(ProductOrderQuery query) {
        return productOrderDao.list(query);
    }

    @Override
    public Page<ProductOrder> search(ProductOrderQuery query) {
        return productOrderDao.search(query);
    }

    @Override
    public ProductOrder check(ProductOrderQuery query) {
        List<ProductOrder> list = productOrderDao.list(query);
        if (!list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public Integer count(ProductOrderQuery query) {
        List<ProductOrder> list = productOrderDao.list(query);
        return list.size();
    }

    @Override
    public synchronized void pay(Charge charge) {
        ProductOrderQuery productOrderQuery = new ProductOrderQuery();
        productOrderQuery.setNo(charge.getOrderNo().trim());
        productOrderQuery.setState(0);
        ProductOrder order = check(productOrderQuery);
        if (order != null) {

            order.setUpdateTime(new Date());
            order.setPay(charge.getAmount()/100.0);
            order.setState(2);//已付款
            order.setCallback(charge.getId());
            order.setStatements("已付款");
            order = productOrderDao.save(order);

            String remark = "";//支付方式
            Money myMoney = moneyManager.mine(order.getUser());
            if (order.getPayment() == 0) {//0支付宝支付，1微信支付
                remark = "支付宝支付";
            } else if (order.getPayment() == 1) {
                remark = "微信支付";
            }else if(order.getPayment()==2){//余额支付
                remark = "余额支付";
                myMoney = moneyManager.frozen(myMoney, -order.getPrice());
            }
            //todo 需要补全money表信息 增加用户支出记录
            billManager.calc(order.getUser(), ShopDataVar.billCategory.用户.toString(), ShopDataVar.billType.消费支出.toString(), 0.0, order.getPay(),myMoney.getBalance(), "productOrder", order.getNo(), remark, 1, null);

            orderStepManager.save("付款成功", "付款成功", order);//新增订单步骤
            notificationManager.save(order.getUser(),Notification.Category.订单消息.toString(),"付款成功","请等待客服与您联系","","productOrder",order.getId().toString());
            GetuiUtil.pushMessage(order.getUser().getClientId(), "订单消息通知", "您的订单已支付完成，请等待客服人员联系", "productOrder", order.getId().toString());

            updateSales(order);//更新销售额

            //增加平台收入和记录
            Finance platFormFinance=financeManager.balance(order.getPrice());
            billManager.calc(null, ShopDataVar.billCategory.平台.toString(), ShopDataVar.billType.平台订单收入.toString(), order.getPrice(),0.0 , platFormFinance.getBalance(), "productOrder", order.getNo(), "", 1, null);


        }
    }


    @Override
    public ProductOrder save(ProductOrder productOrder, User user, List<Cart> carts, Address address) {
        if (productOrder.getUserCoupon() != null && productOrder.getUserCoupon().getId() != null) {//是否使用红包
            UserCoupon userCoupon = userCouponManager.get(productOrder.getUserCoupon().getId());
            userCouponManager.useCoupon(userCoupon);
        }

        Double price = 0.00; //订单总价格
        Double origPrice = 0.00; //订单原价
        for (Cart cart : carts) {
            ProductItem productItem = cart.getProductItem();
            origPrice += productItem.getPrice() * cart.getQuantity();
            price += productItem.getPrice() * cart.getQuantity();//计算订单总价格
        }
        productOrder.setPrice(price - productOrder.getDiscount() - productOrder.getCoupon());//计算商品实际价格(减去手工优惠价格-减去优惠金额)
        productOrder.setOrigPrice(origPrice);
        productOrder.setState(0);//待付款
        productOrder.setStatements("待付款");
        productOrder.setUser(user);
        productOrder.setCategory("用户订单");
        productOrder = updateAddress(productOrder, address);
        productOrder = productOrderDao.save(productOrder);

        for (Cart cart : carts) {
            ProductItem productItem = cart.getProductItem();
            OrderItem orderItem = new OrderItem();
            orderItem.setProductOrder(productOrder);
            orderItem.setProduct(productItem.getProduct());
            orderItem.setProductItem(productItem);
            orderItem.setNo(productOrder.getNo());
            orderItem.setType("");
            orderItem.setPrice(productItem.getPrice());
            orderItem.setOrigPrice(productItem.getPrice());
            orderItem.setQuantity(cart.getQuantity());
            orderItem.setUser(user);
            orderItem.setType("原价");
            orderItem = orderItemManager.save(orderItem);
        }
        orderStepManager.save("提交订单", "提交订单", productOrder);//新增订单步骤


        return productOrder;
    }

    @Override
    public ProductOrder save(ProductOrder productOrder, User user, String productItemIds, String quantities, Address address) {
        if (productOrder.getUserCoupon() != null && productOrder.getUserCoupon().getId() != null) {//是否使用红包
            UserCoupon userCoupon = userCouponManager.get(productOrder.getUserCoupon().getId());
            userCouponManager.useCoupon(userCoupon);
        }

        productOrder.setNo(OrderUtil.getOrderNo());
        Double price = 0.00; //订单总价格
        Double origPrice = 0.00; //订单原价
        String[] productItemIdArray = productItemIds.split(",");//药品ID数组
        String[] quantityArray = quantities.split(",");//药品数量数组
        for (int i = 0; i < productItemIdArray.length; i++) {
            ProductItem productItem = productItemManager.get(Integer.valueOf(productItemIdArray[i]));
            if (productItem != null) {
                origPrice += productItem.getPrice() * Integer.valueOf(quantityArray[i]);
                price += productItem.getPrice() * Integer.valueOf(quantityArray[i]);//计算订单总价格
            }
        }
        productOrder.setPrice(price - productOrder.getDiscount() - productOrder.getCoupon());//计算商品实际价格(减去手工优惠价格-减去优惠金额)
        productOrder.setOrigPrice(origPrice);
        productOrder.setState(0);//待付款
        productOrder.setStatements("待付款");
        productOrder.setCategory("用户订单");
        productOrder.setUser(user);
        productOrder = updateAddress(productOrder, address);
        productOrder = productOrderDao.save(productOrder);
        for (int i = 0; i < productItemIdArray.length; i++) {
            ProductItem productItem = productItemManager.get(Integer.valueOf(productItemIdArray[i]));
            if (productItem != null) {
                OrderItem orderItem = new OrderItem();
                orderItem.setProductOrder(productOrder);
                orderItem.setProduct(productItem.getProduct());
                orderItem.setProductItem(productItem);
                orderItem.setNo(productOrder.getNo());
                orderItem.setType("");
                orderItem.setPrice(productItem.getPrice());
                orderItem.setOrigPrice(productItem.getPrice());
                orderItem.setQuantity(Integer.valueOf(quantityArray[i]));
                orderItem.setUser(user);
                orderItem.setType("原价");
                orderItem = orderItemManager.save(orderItem);
            }
        }

        orderStepManager.save("提交订单", "提交订单", productOrder);//新增订单步骤

        return productOrder;
    }

    @Override
    public ProductOrder cancel(ProductOrder productOrder) {
        productOrder.setUpdateTime(new Date());
        productOrder.setState(-1);
        productOrder.setStatements("用户已取消订单");
        productOrder = productOrderDao.save(productOrder);

        userCouponManager.turnBackUserCoupon(productOrder.getUserCoupon());//退还优惠券

        orderStepManager.save("订单已取消", "订单已取消", productOrder);//新增订单步骤

        return productOrder;
    }

    @Override
    public List<ProductOrder> list(String hql, Object[] params) {
        return productOrderDao.list(hql, params);
    }

    //    退款
    public synchronized void refund(Refund refund) {
        ProductOrderQuery productOrderQuery = new ProductOrderQuery();
        productOrderQuery.setCallback(refund.getCharge().trim());
        productOrderQuery.setRefundState(2);
        ProductOrder productOrder = check(productOrderQuery);
        if (productOrder != null) {
            productOrder.setUpdateTime(new Date());
            productOrder.setRefundState(1);//已退款
            productOrder.setStatements("已退款");
            productOrder.setState(-1);
            productOrder = productOrderDao.save(productOrder);

            //增加用户退款记录
            billManager.calc(productOrder.getUser(), ShopDataVar.billCategory.用户.toString(), ShopDataVar.billType.消费退款.toString(), 0.0, productOrder.getPay(), 0.0, "order", productOrder.getNo(), null, 1, null);

            userCouponManager.turnBackUserCoupon(productOrder.getUserCoupon());//退还优惠券

            //Finance 表 变化
//            Finance finance = financeManager.get(1);
//            financeManager.balance(-productOrder.getPrice());
            //增加店铺 订单退款记录
//            billManager.calcShop(productOrder.getShop(), "店铺", CommonVar.BillType.订单退款.toString(), 0.0, productOrder.getPrice(), 0.0, "order", productOrder.getNo(), null, 1, null);

            notificationManager.save(productOrder.getUser(),Notification.Category.订单消息.toString(),"订单已退款","您的订单已退款到原来的账户中","","productOrder",productOrder.getId().toString());
            GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", "您的订单已退款到原来的账户中", "productOrder", productOrder.getId().toString());

            orderStepManager.save("订单已取消", "订单已取消", productOrder);//新增订单步骤


            //添加平台线上退款和记录
            Finance platFormFinance=financeManager.balance(-productOrder.getRefundAmount());
            billManager.calc(null, ShopDataVar.billCategory.平台.toString(), ShopDataVar.billType.平台线上退款.toString(), 0.0,productOrder.getRefundAmount() , platFormFinance.getBalance(), "productOrder", productOrder.getNo(), "", 1, null);



        }
    }

    @Override
    public ProductOrder executeRefund(ProductOrder productOrder, Double refundPrice) {
        //退款流程
        Pingpp.apiKey = PingConfig.APIKEY;
        Pingpp.setVerifySSL(Boolean.FALSE);

        productOrder.setRefundAmount(StringUtil.toDecimal(refundPrice, 2));
        productOrder = productOrderDao.save(productOrder);
        if (StringUtils.isEmpty(productOrder.getCallback())) {
            return productOrder;
        }

        try {
            if (refundPrice > productOrder.getPay()) {
                refundPrice = productOrder.getPay();
            }

            try {
                //当前退款金额小于上一笔支付金额
                Charge ch = Charge.retrieve(productOrder.getCallback());
                Map<String, Object> refundMap = new HashMap<String, Object>();
                refundMap.put("amount", (int) (StringUtil.toDecimal(refundPrice, 2) * 100));
                refundMap.put("description", "订单退货退款");
                Map<String, String> initialMetadata = new HashMap<String, String>();
                initialMetadata.put("order_type", "productOrder");
                refundMap.put("metadata", initialMetadata);
                Refund re = ch.getRefunds().create(refundMap);
            } catch (Exception e) {
                e.printStackTrace();
            }
            productOrder.setUpdateTime(new Date());
            productOrder.setRefundState(2);//退款中
            productOrder.setStatements("退款中,请耐心等待");
            productOrder.setRefundAmount(StringUtil.toDecimal(refundPrice, 2));
            productOrder = productOrderDao.save(productOrder);

            GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", " 您的订单正在办理退款，资金到账时间1-2个工作日", "productOrder", productOrder.getId().toString());

            return productOrder;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public ProductOrder conform(ProductOrder productOrder) {

        productOrder.setUpdateTime(new Date());
        productOrder.setHandleState(3);//3已验收
        productOrder.setState(1);//已完成
        productOrder.setStatements("用户已验收,等待评价");
        productOrder = productOrderDao.save(productOrder);

        notificationManager.save(productOrder.getUser(),Notification.Category.订单消息.toString(),"请尽快评价","您的订单尚未评价，请尽快评价","","productOrder",productOrder.getId().toString());
        GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", "您的订单尚未评价，请尽快评价", "productOrder", productOrder.getId().toString());

        orderStepManager.save("完成", "完成", productOrder);//新增订单步骤

        return productOrder;
    }

    @Override
    public void updateSales(ProductOrder productOrder) {
        List<OrderItem> orderItems = orderItemManager.list(new OrderItemQuery(productOrder.getId()));
        for (OrderItem item : orderItems) {
            Product product = item.getProduct();
            if (product.getMonthSales() == null) {
                product.setMonthSales(0);
            }
            product.setMonthSales(product.getMonthSales() + item.getQuantity());
            product = productManager.save(product);
        }

    }

    @Override
    public ProductOrder updateAddress(ProductOrder productOrder, Address address) {
        if (address == null) {
            return productOrder;
        }
        productOrder.setDistrict(address.getDistrict());
        productOrder.setCity(address.getCity());
        productOrder.setProvince(address.getProvince());
        productOrder.setAddress(address.getAddr());
        productOrder.setAddrName(address.getName());
        productOrder.setAddrMobile(address.getMobile());
        return productOrder;
    }

    @Override
    public ProductOrder contact(ProductOrder productOrder,Boolean ifCanDo) {
        if(ifCanDo){//升级为处理中
            orderStepManager.save("已联系", "已联系", productOrder);//新增订单步骤
            productOrder.setUpdateTime(new Date());
            productOrder.setStatements("待量房");
            productOrder.setState(3);//3处理中
            productOrder.setHandleState(0);//0待量房（已联系）

            notificationManager.save(productOrder.getUser(),Notification.Category.订单消息.toString(),"请等待量房哦","您的订单已接受，等待施工人员上门量房","","productOrder",productOrder.getId().toString());
            GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", "您的订单已接受，等待施工人员上门量房", "productOrder", productOrder.getId().toString());

        }else {
            executeRefund(productOrder, productOrder.getPay());//直接退款
        }

        return productOrderDao.save(productOrder);
    }

    @Override
    public ProductOrder waitExecution(ProductOrder productOrder) {
        productOrder.setUpdateTime(new Date());
        productOrder.setStatements("待施工");
        productOrder.setHandleState(1);//待施工

        orderStepManager.save("等待施工","等待施工",productOrder);//新增订单步骤

        notificationManager.save(productOrder.getUser(),Notification.Category.订单消息.toString(),"请等待施工","您的订单满足施工的要求，请等待施工人员上门施工","","productOrder",productOrder.getId().toString());
        GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", "您的订单满足施工的要求，请等待施工人员上门施工", "productOrder", productOrder.getId().toString());

        return productOrderDao.save(productOrder);
    }

    @Override
    public ProductOrder execution(ProductOrder productOrder) {
        productOrder.setUpdateTime(new Date());
        productOrder.setStatements("待验收");
        productOrder.setState(3);//3处理中
        productOrder.setHandleState(2);//2待验收（已施工）
        orderStepManager.save("已施工", "已施工", productOrder);//新增订单步骤

        notificationManager.save(productOrder.getUser(),Notification.Category.订单消息.toString(),"施工完毕","您的项目已经施工完成，请验收。","","productOrder",productOrder.getId().toString());
        GetuiUtil.pushMessage(productOrder.getUser().getClientId(), "订单消息通知", "您的项目已经施工完成，请验收。", "productOrder", productOrder.getId().toString());

        return productOrderDao.save(productOrder);
    }


}